import { Inject, Provide } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Repository } from "typeorm";
import { DeptEntity } from "@entity/system/dept.entity";
import { UserEntity } from "@entity/system/user.entity";
import { ListDeptDTO, CreateDeptDTO, UpdateDeptDTO } from "@dto/system/dept.dto";
import { resBuild } from "@utils/resBuild";
import { checkKeyIsExist } from "@utils/serviceHelp";
import { listToTree } from "@utils/tree";
import { getOperator } from "@utils";

@Provide()
export class DeptService {
  @Inject()
  ctx: Context;

  @InjectEntityModel(DeptEntity)
  deptEntity: Repository<DeptEntity>;

  @InjectEntityModel(UserEntity)
  userEntity: Repository<UserEntity>;

  // 列表
  async list(queryParams: ListDeptDTO) {
    const queryBuilder = this.deptEntity.createQueryBuilder('entity');
    if(queryParams.deptName) {
      queryBuilder.andWhere(`entity.deptName like "%${queryParams.deptName}%"`)
    }
    if(queryParams.status) {
      queryBuilder.andWhere(`entity.status = ${queryParams.status}`)
    }
    queryBuilder.addOrderBy('entity.orderNum', 'ASC')
    queryBuilder.addOrderBy('entity.createTime', 'DESC')
    const rows = await queryBuilder.getMany()
    return resBuild.data(rows)
  }

  // 添加
  async create(dept: CreateDeptDTO) {
    // 新增之前先判断是否已存在
    await checkKeyIsExist(this.deptEntity,'deptName', dept.deptName)

    // 查询父级部门信息，把ancestors参数加上去
    const parentRecord = await this.deptEntity.findOneBy({
      deptId: dept.parentId
    })
    const ancestors = parentRecord.ancestors ? (parentRecord.ancestors + ',' + dept.parentId) : parentRecord.ancestors

    // 执行新增
    const myEntity = this.deptEntity.create(Object.assign(dept, { ancestors }));
    myEntity.setCreateBy(getOperator(this.ctx))
    await this.deptEntity.save(myEntity);

    return resBuild.success()
  }

  // 删除：先判断部门下是否有子节点，再判断部门下是否有人，如果有则提示，没有则删除
  async delete(deptId: number) {

    const queryBuilder = this.deptEntity.createQueryBuilder('dept');
    queryBuilder.andWhere('FIND_IN_SET(:deptId, dept.ancestors) > 0', { deptId })
    const rows = await queryBuilder.getMany();
    if(rows.length > 0) {
      throw new Error('存在子节点，不能删除');
    }

    // 部门下是否有用户
    const isDeptIncludesUser = await this.userEntity.find({
      where: {
        deptId
      }
    })
    if(isDeptIncludesUser.length > 0) {
      throw new Error('部门下存在用户，不能删除');
    }

    const isLevelOne = await this.deptEntity.findOne({
      where: {
        parentId: 0,
        deptId
      }
    })
    if(isLevelOne) {
      throw new Error('当前部门为一级部门，不能删除');
    }

    await this.deptEntity.delete(deptId);
    return resBuild.success()
  }

  // 修改
  async update(dept: UpdateDeptDTO) {
    const myEntity = this.deptEntity.create(dept);
    myEntity.setUpdateBy(getOperator(this.ctx))
    await this.deptEntity.save(dept);
    return resBuild.success()
  }

  // 详情
  async detail(deptId: number) {
    const detailInfo = await this.deptEntity.findOneBy({
      deptId,
    });
    return resBuild.data(detailInfo)
  }

  // 详情的一不分、排除子节点
  async excludeChild() {
    const deptId = this.ctx.params.deptId;
    const queryBuilder = this.deptEntity.createQueryBuilder('dept');
    queryBuilder.where('dept.deptId != :deptId', { deptId });
    queryBuilder.andWhere('FIND_IN_SET(:ancestors, dept.ancestors) = 0', { ancestors: deptId })
    const rows = await queryBuilder.getMany();
    return resBuild.data(rows)
  }

  // 树状结构，用户列表页用
  async deptTree() {
    // 从部门表取关键数据
    const rows = await this.deptEntity.find({
      select: ['deptId', 'parentId', 'deptName'],
    });
    // 构造树状结构
    const deptTreeList = listToTree(rows, 'deptId', 'deptName');
    return resBuild.data(deptTreeList)
  }
}
